﻿#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;

namespace PHMEE.EnergyEfficiency;

/// <summary>
/// 航次（含不完整的航次）(“离港”到“离港”] 前开后闭区间为一个航次
/// </summary>
public class Voyage
{
    /// <summary>
    /// 航次内的 log abstracts
    /// </summary>
    public List<LogAbstract> LogAbstracts { get; set; } = [];

    /// <summary>
    /// 航次开始的离港 log abstract（航次不含该 log abstract）
    /// </summary>
    public LogAbstract? StartDepartureLogAbstract { get; set; }

    /// <summary>
    /// 航次结束的离港 log abstract（航次含该 log abstract）
    /// </summary>
    public LogAbstract? EndDepartureLogAbstract { get; set; }

    /// <summary>
    /// 开始时间（如果航次头部被查询的日期范围所截断，StartTime 就是第一个 log abstract 的 Ts）
    /// </summary>
    public DateTime StartTime { get; set; }

    /// <summary>
    /// 结束时间（如果航次尾部被查询的日期范围所截断，EndTime 就是最后一个 log abstract 的 Ts）
    /// </summary>
    public DateTime EndTime { get; set; }

    /// <summary>
    /// 结束时间与开始时间之间的小时数（精确到小数）
    /// </summary>
    public float HoursUnderway => (float)(EndTime - StartTime).TotalHours;

    /// <summary>
    /// 是否包含 STS 作业
    /// </summary>
    public bool IsSTS => LogAbstracts.Any(la => LogAbstractEventTypeHelper.STSEvents.Contains(la.Event));

    /// <summary>
    /// 是否是 MRV 航次
    /// </summary>
    public bool IsMRV
    {
        get
        {
            // 当 StartDepartureLogAbstract 和 EndDepartureLogAbstract 都为空时，返回 false
            // 否则有任何一个的 event 为 DepartureEU 就返回 true
            if (StartDepartureLogAbstract == null && EndDepartureLogAbstract == null)
            {
                return false;
            }

            if ((StartDepartureLogAbstract != null &&
                 StartDepartureLogAbstract.Event == LogAbstractEventType.DepartureEU) ||
                (EndDepartureLogAbstract != null && EndDepartureLogAbstract.Event == LogAbstractEventType.DepartureEU))
            {
                return true;
            }

            return false;
        }
    }
}

public static class VoyageExtensions
{
    /// <summary>
    /// 获取全部航次的总小时数
    /// </summary>
    /// <param name="voyages"></param>
    /// <returns></returns>
    public static float GetTotalHours(this List<Voyage> voyages)
    {
        float totalHours = 0;
        foreach (var voyageDto in voyages)
        {
            totalHours += voyageDto.HoursUnderway;
        }

        return totalHours;
    }
    
    /// <summary>
    /// 获取 voyages 中全部 STS 作业的 LogAbstracts
    /// </summary>
    /// <param name="voyages"></param>
    /// <returns></returns>
    public static List<LogAbstract> GetSTSLogAbstracts(this List<Voyage> voyages)
    {
        List<LogAbstract> stsLogAbstracts = [];
        
        foreach (var voyage in voyages)
        {
            if (voyage.IsSTS)
            {
                // 遍历航次中的 LogAbstracts，将 ArrivalSTS（不含） 和 DepartureSTS 以及它们之间的所有 LogAbstract 添加到 stsLogAbstracts 中
                bool isSTSLogAbstract = false;
                foreach (var logAbstract in voyage.LogAbstracts)
                {
                    if (logAbstract.Event == LogAbstractEventType.ArrivalSTS)
                    {
                        isSTSLogAbstract = true;
                        // 不含 ArrivalSTS
                        continue;
                    }

                    if (isSTSLogAbstract)
                    {
                        stsLogAbstracts.Add(logAbstract);
                    }
                    
                    if (logAbstract.Event == LogAbstractEventType.DepartureSTS)
                    {
                        isSTSLogAbstract = false;
                    }
                }
            }
        }

        return stsLogAbstracts;
    }
}